package org.example.POJO.game;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.example.Page.GamePanel;

import javax.swing.*;
import java.awt.*;
import java.io.Serializable;

@Data
@NoArgsConstructor
public abstract class Chess implements Serializable {
    //棋子大小
    private static final int SIZE = 40;
    //棋盘外边距
    private static final int MARGIN = 30;
    //棋子间距
    private static final int SPACE = 48;
    //棋子名称
    private String name;
    //图片后缀
    private String suffix = ".gif";
    //棋子阵营
    protected int camp;
    //棋子绘制时的坐标
    private int x, y;
    //棋子网格坐标
    protected Point point;
    //初始位置，不能改变
    private Point initP;
    //初始每个棋子索引
    private int index;

    public void draw(Graphics g, JPanel jPanel){
        String path ="picture/qizi/"+name +camp+suffix;
        Image image = Toolkit.getDefaultToolkit().getImage(path);
        g.drawImage(image,x,y,SIZE,SIZE,jPanel);
    }

    //给当前选中的棋子画边框
    public void drawBorder(Graphics g, JPanel jPanel){
        String path ="picture/qizi/select.gif";
        Image image = Toolkit.getDefaultToolkit().getImage(path);
       g.drawImage(image,x,y,SIZE,SIZE,jPanel);
    }

    public void setPoint(Point p) {
        this.point = (Point) p.clone();//给了副本的坐标
        if (initP == null) {
            initP = this.point;
        }
        calXY();
    }

    public Point getPoint() {
        return point;
    }

    public Chess(String name, int camp, Point p) {
        this.name = name;
        this.camp = camp;
        setPoint(p);
    }

    public Chess(String name, Point p, int camp) {
        this.name = name;
        this.camp = camp;
        setPoint(p);
    }

    /*
     * 计算xy的绘制网格坐标
     * */
    public void calXY(){
        x = MARGIN - SIZE /2 +SPACE * (point.x - 1);
        y = MARGIN - SIZE /2 +SPACE * (point.y - 1);
    }

    public void reserve(){
        point.x = 10 - point.x;
        point.y = 11 - point.y;
        initP =point;
        calXY();
    }

    //根据鼠标的点击反求棋子坐标
    public static Point getPointFromXY(int x, int y) {
        Point p = new Point();
        p.x = (x - MARGIN + SIZE / 2) / SPACE + 1;
        p.y = (y - MARGIN + SIZE / 2) / SPACE + 1;
        if (p.x < 1 || p.x > 9 || p.y < 1 || p.y > 10) {
            return null;
        }
        return p;
    }

    //判断棋子是否能够移动到指定位置
    public abstract boolean isAbleMove(Point tp, GamePanel gamePanel);
    /*判断棋子在上半边还是下半边
    * 1:上半边 2:下半边
    * */
    public int isTopOrDown(){
        //判断是在上面还是下面
        if(initP.y <6){
            //上面
            return 1;}
        else if(initP.y > 5){
            //下面
            return 2;}
        return 0;
    }

    //判断是否能在王宫移动
    public boolean isInWangGong(Point tp){
        if (tp.x < 4 || tp.x > 6){
            return false;
        }
        int topOrDown = isTopOrDown();
        if(topOrDown == 1){
            //上面
            if(tp.y > 3 || tp.y < 1){
                return false;
            }}
        else if(topOrDown == 2){
            //下面
            if(tp.y < 8 || tp.y > 10){
                return false;
            }}
        return true;
    }
    
    /*判断是否走直线或者斜线或日字
    * 1:斜线 2:y轴 3:x轴 0:x日字 -1:y日字 -2:无
    * */
    public int isLine(Point tp){
        if (point.y == tp.y) {
            //x
            return 3;
        } else if (point.x == tp.x) {
            //y
            return 2;
        } else if (Math.abs(point.x - tp.x) == Math.abs(point.y - tp.y)) {
            //正斜线
            return 1;
        } else {
            //日字
            if (Math.abs(point.x - tp.x) == 2 && Math.abs(point.y - tp.y) == 1) {
                //x
                return 0;
            } else if (Math.abs(point.x - tp.x) == 1 && Math.abs(point.y - tp.y) == 2) {
                //y
                return -1;
            }
        }

        return -2;
    }

    //计算起点到目标点的步数
    //1:斜线 2:y轴 3:x轴
    public int getStep(Point tp){
        int line = isLine(tp);
        if(line == 3){
            //x轴
            return Math.abs(point.x - tp.x);
        }
        else if(line == 2){
            //y轴
            return Math.abs(point.y - tp.y);
        }
        else if(line == 1){
            //正斜线
            return Math.abs(point.x - tp.x);
        }
        return 0;
    }
    //是否象或马阻挡
    public boolean isBlock(Point tp, GamePanel gamePanel){
        Point center = new Point();
        if("xiang".equals(name)){
            //求中心点
            center.x = (point.x + tp.x) / 2;
            center.y = (point.y + tp.y) / 2;
            //判断中间点是否有棋子
            return gamePanel.getChessByP(center) != null;
        }
        else if ("ma".equals(name)) {
            int line = isLine(tp);
            if(line == 0){
                //x
                center.x = (point.x + tp.x) / 2;
                center.y = point.y;
            }
            else if (line == -1) {
                //y
                center.y = (point.y + tp.y) / 2;
                center.x = point.x;

            }
            return gamePanel.getChessByP(center) != null;
        }
        return true;
        }
        //判断目标点是否过河
    public boolean isPassRiver(Point tp){
        int upOrDown = isTopOrDown();
        if(upOrDown == 1){
            //上面
            if(tp.y < 6){
                return false;
            }
        }
        else if(upOrDown == 2){
            //下面
            if(tp.y > 5){
                return false;
            }
        }
        return true;
    }

    //计算起点到目标点之间的棋子数量，不计算起点和目标点上的位置
    public int getCount(Point tp, GamePanel gamePanel) {
        int start = 0;
        int end = 0;
        int count = 0;//统计棋子数量
        int line = isLine(tp);
        Point np = new Point();
        if (line == 2) {
            //y
            np.x = tp.x;
            if (tp.y > point.y) {
                //从上往下
                start = point.y + 1;
                end = tp.y;
            } else {
                //从下往上
                start = tp.y + 1;
                end = point.y;
            }
            for (int i = start; i < end; i++) {
                np.y = i;
                if (gamePanel.getChessByP(np) != null) {
                    count++;
                }
            }
        }else if (line == 3) {
            //x
            np.y = tp.y;
            if (tp.x > point.x) {
                //从左往右
                start = point.x + 1;
                end = tp.x;
            } else {
                //从右往左
                start = tp.x + 1;
                end = point.x;
            }
            for (int i = start; i < end; i++) {
                np.x = i;
                if (gamePanel.getChessByP(np) != null) {
                    count++;
                }
            }
        }
        return count;
    }
    public boolean isForward(Point tp) {
        int upOrDown = isTopOrDown();
        if (upOrDown == 1) {
            //上
            if (tp.y > point.y) {
                return true;
            }
        } else if (upOrDown == 2) {
            //下
            if (tp.y < point.y) {
                return true;
            }
        }

        return false;
    }

    public boolean isBack(Point tp) {
        int upOrDown = isTopOrDown();
        if (upOrDown == 1) {
            //上
            if (tp.y < point.y) {
                return true;
            }
        } else if (upOrDown == 2) {
            //下
            if (tp.y > point.y) {
                return true;
            }
        }

        return false;
    }
    }
